//////////////////////////////////////////////////////////////////////
// Reg.cpp: implementation of the CReg class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Reg.h"


//=======================================================================
//Macro define
#define MyFree(p)            { if(p) LocalFree(p); }
//=======================================================================
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CReg::CReg()
{
	m_hKey = NULL;
	m_Index = 0;
	m_lpbValue = NULL;
}

CReg::CReg(HKEY hkRoot, LPCTSTR pszKey)
{
	m_hKey = NULL;
	m_Index = 0;
	m_lpbValue = NULL;
	Open(hkRoot, pszKey);
}


CReg::~CReg()
{
	if(m_hKey)
	{
		RegCloseKey(m_hKey);
	}
	MyFree(m_lpbValue);
}


//-------------------------------------------------------------------
//Description:
//    Create the key
//-------------------------------------------------------------------
BOOL CReg::Create(HKEY hkRoot, LPCTSTR pszKey)
{
	DWORD dwDisp;
	return ERROR_SUCCESS == RegCreateKeyEx(hkRoot, pszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_hKey, &dwDisp);
}


//-------------------------------------------------------------------
//Description:
//    Open the key
//-------------------------------------------------------------------
BOOL CReg::Open(HKEY hkRoot, LPCTSTR pszKey, REGSAM sam)
{
	return ERROR_SUCCESS == RegOpenKeyEx(hkRoot, pszKey, 0, sam, &m_hKey);
}

//-------------------------------------------------------------------
//Description:
//    Reset the value
//-------------------------------------------------------------------
void CReg::Reset()
{
	if(m_hKey)
	{
		RegCloseKey(m_hKey); 
	}
	MyFree(m_lpbValue);
	m_hKey = NULL;
	m_Index = 0;
	m_lpbValue = NULL;
}

//-------------------------------------------------------------------
//Description:
//    Operator overload
//-------------------------------------------------------------------
CReg::operator HKEY()
{
	return m_hKey;
}

//-------------------------------------------------------------------
//Description:
//    Test whether is the handle of the key OK for next operate
//-------------------------------------------------------------------
BOOL CReg::IsOK()
{
	return m_hKey != NULL;
}


//-------------------------------------------------------------------
//Description:
//    Enum the key
//-------------------------------------------------------------------
BOOL CReg::EnumKey(LPTSTR psz, DWORD dwLen)
{
	if(!m_hKey)
	{
		return FALSE;
	}

	return ERROR_SUCCESS == RegEnumKeyEx(m_hKey, m_Index++, psz, &dwLen, NULL, NULL, NULL, NULL);
}


//-------------------------------------------------------------------
//Description:
//    Enum registry Value
//-------------------------------------------------------------------
BOOL CReg::EnumValue(LPTSTR pszName, DWORD dwLenName, LPTSTR pszValue, DWORD dwLenValue)
{
	DWORD dwType;

	if(!m_hKey) 
	{
		return FALSE;
	}

	dwLenValue *= sizeof(TCHAR); // convert length in chars to bytes

	return ERROR_SUCCESS == RegEnumValue(m_hKey, m_Index++, pszName, &dwLenName, NULL, &dwType, (LPBYTE)pszValue, &dwLenValue);
}


//-------------------------------------------------------------------
//Description:
//    Get the string value
//-------------------------------------------------------------------
BOOL CReg::GetValueSZ(LPCTSTR szName, LPTSTR szValue, DWORD dwLen)
{
	if(!m_hKey)
	{
		return FALSE;
	}

	dwLen *= sizeof(TCHAR); // convert length in chars to bytes

	return ERROR_SUCCESS == RegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)szValue, &dwLen);
}

//-------------------------------------------------------------------
//Description:
//    Get the binary value
//-------------------------------------------------------------------
DWORD CReg::GetValueBinary(LPCTSTR szName, LPBYTE lpbValue, DWORD dwLen)
{
	if(!m_hKey) 
	{
		return FALSE;
	}

	DWORD dwLenWant = dwLen;
	if(ERROR_SUCCESS == RegQueryValueEx(m_hKey, szName, NULL, NULL, lpbValue, &dwLen))
	{
		return dwLen;
	}
	else
	{
		return 0;
	}
}


//-------------------------------------------------------------------
//Description:
//    Get the binary value
//-------------------------------------------------------------------
LPBYTE CReg::GetValueBinary(LPCTSTR szName)
{
	return (LPBYTE)GetValueSZ(szName);
}


//-------------------------------------------------------------------
//Description:
//    Get the string value
//-------------------------------------------------------------------
LPCTSTR CReg::GetValueSZ(LPCTSTR szName)
{
	return 0;
}


//-------------------------------------------------------------------
//Description:
//    Get the DWORD value
//
//Parameters:
//    szName:[in] The value of registry
//    dwDefault:[in] The default value return when failed in getting the 
//DWORD value.
//-------------------------------------------------------------------
DWORD CReg::GetValueDW(LPCTSTR szName, DWORD dwDefault)
{
	if(!m_hKey) 
	{
		return FALSE;
	}
	DWORD dwValue = dwDefault;
	DWORD dwLen = sizeof(DWORD);
	RegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)&dwValue, &dwLen);
	return dwValue;
}


//-------------------------------------------------------------------
//Description:
//    Set the string value
//-------------------------------------------------------------------
BOOL CReg::SetSZ(LPCTSTR szName, LPCTSTR szValue, DWORD dwLen)
{
	//Prefix
	if(!m_hKey) 
	{
		return FALSE;
	}

	return ERROR_SUCCESS == RegSetValueEx(m_hKey, szName, 0, REG_SZ, (LPBYTE)szValue, sizeof(TCHAR)*dwLen);
}


//-------------------------------------------------------------------
//Description:
//    Set the string value
//-------------------------------------------------------------------
BOOL CReg::SetSZ(LPCTSTR szName, LPCTSTR szValue)
{
	return SetSZ(szName, szValue, 1+lstrlen(szValue));
}


//-------------------------------------------------------------------
//Description:
//    Get the DWORD value
//-------------------------------------------------------------------
BOOL CReg::SetDW(LPCTSTR szName, DWORD dwValue)
{
	//Prefix
	if(!m_hKey) 
	{
		return FALSE;
	}

	return ERROR_SUCCESS==RegSetValueEx(m_hKey, szName, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
}


//-------------------------------------------------------------------
//Description:
//    Get the binary value
//-------------------------------------------------------------------
BOOL CReg::SetBinary(LPCTSTR szName, LPBYTE lpbValue, DWORD dwLen)
{
	//Prefix
	if(!m_hKey) 
	{
		return FALSE;
	}

	return ERROR_SUCCESS == RegSetValueEx(m_hKey, szName, 0, REG_BINARY, lpbValue, dwLen);
}


//-------------------------------------------------------------------
//Description:
//    Set the Multi value
//-------------------------------------------------------------------
BOOL CReg::SetMultiSZ(LPCTSTR szName, LPCTSTR lpszValue, DWORD dwLen)
{
	return ERROR_SUCCESS == RegSetValueEx(m_hKey, szName, 0, REG_MULTI_SZ, (LPBYTE)lpszValue, sizeof(TCHAR)*dwLen);
}


//-------------------------------------------------------------------
//Description:
//    Delete the value
//-------------------------------------------------------------------
BOOL CReg::DeleteValue(LPCTSTR szName)
{
	//Prefix
	if(!m_hKey) 
	{
		return FALSE;
	}
	//
	return ERROR_SUCCESS == RegDeleteValue(m_hKey, szName);
}



//-------------------------------------------------------------------
//Description:
//    Delete Key
//-------------------------------------------------------------------
BOOL CReg::DeleteKey(LPCTSTR szName)
{
	if(!m_hKey) 
	{
		return FALSE;
	}

	return ERROR_SUCCESS == RegDeleteKey(m_hKey, szName);
}
